﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.IO;
using System.Globalization;
using Dzzzr;
using NWS;
using System.Web.Security;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;

namespace NWSforWEB.Models
{
	/// <summary>
	/// Class for accesing game data
	/// </summary>
	public class GameModel : NWSforWEB.Models.IGameModel
	{
		/// <summary>
		/// Constructor
		/// </summary>
		public GameModel()
		{
		}

		/// <summary>
		/// Get all Games for current team
		/// </summary>
		/// <returns></returns>
		public Game[] GetGameList()
		{
			List<Game> games = Game.GetGameList(TeamID);
			return games.ToArray<Game>();
		}

		/// <summary>
		/// Add point to entity
		/// </summary>
		/// <param name="entityID"></param>
		/// <param name="latitude"></param>
		/// <param name="longitude"></param>
		public void AddPoint(int gameID, int entityID, float latitude, float longitude)
		{
			AddPoint(entityID, gameID, (int)Membership.GetUser().ProviderUserKey, latitude, longitude, 0, 0);
		}


		/// <summary>
		/// Get all markers
		/// </summary>
		/// <param name="gamename"></param>
		/// <returns></returns>
		public Marker[] GetMarkers(int gameID)
		{
			return GetMarkerList(gameID).ToArray<Marker>();
		}

		/// <summary>
		/// Get marker
		/// </summary>
		/// <param name="markerID"></param>
		/// <returns></returns>
		public Marker GetMarker(int gameID, int markerID)
		{
			return (from m in GetMarkerList(gameID) where m.ID == markerID select m).SingleOrDefault();
		}

		/// <summary>
		/// Get points for marker
		/// </summary>
		/// <param name="gameID"></param>
		/// <param name="markerID"></param>
		/// <param name="startDate"></param>
		/// <param name="endDate"></param>
		/// <returns></returns>
		public Marker[] GetMarkerPoints(int gameID, int markerID, DateTime startDate, DateTime endDate)
		{
			return GetMarkerPointsList(gameID, markerID, startDate, endDate).ToArray<Marker>();
		}

		/// <summary>
		/// Get number of points for marker
		/// </summary>
		/// <param name="gameID"></param>
		/// <param name="markerID"></param>
		/// <param name="count"></param>
		/// <param name="endDate"></param>
		/// <returns></returns>
		public Marker[] GetMarkerPointsCount(int gameID, int markerID, int count, DateTime endDate)
		{
			return GetMarkerPointsCountList(gameID, markerID, count, endDate).ToArray<Marker>();
		}

		/// <summary>
		/// Current user name
		/// </summary>
		private static string UserName
		{
			get
			{
				return (string)HttpContext.Current.Session[Constants.CurrentUser];
			}
		}

		/// <summary>
		/// Current user password (hashed)
		/// </summary>
		private static string Password
		{
			get
			{
				return (string)HttpContext.Current.Session[Constants.CurrentPassword];
			}
		}

		private static SqlConnection Connection
		{
			get
			{
				SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString);
				cnn.Open();
				return cnn;
			}
		}

		/// <summary>
		/// TeamID
		/// </summary>
		private static int TeamID
		{
			get
			{
				return (int)HttpContext.Current.Profile["TeamID"];
			}
		}

		/// <summary>
		/// Add point to entity
		/// </summary>
		/// <param name="entityID"></param>
		/// <param name="gameID"></param>
		/// <param name="userID"></param>
		/// <param name="latitude"></param>
		/// <param name="longitude"></param>
		/// <param name="altitude"></param>
		/// <param name="speed"></param>
		private void AddPoint(int entityID, int gameID, int userID, float latitude, float longitude, float altitude, int speed)
		{
			using (SqlConnection cnn = Connection)
			{
				SqlCommand cmd = new SqlCommand("InsertGPSPoint", cnn);
				cmd.CommandType = CommandType.StoredProcedure;
				cmd.Parameters.AddWithValue("@EntityID", entityID);
				cmd.Parameters.AddWithValue("@GameID", gameID);
				cmd.Parameters.AddWithValue("@UserID", userID);
				cmd.Parameters.AddWithValue("@Latitude", latitude);
				cmd.Parameters.AddWithValue("@Longitude", longitude);
				cmd.Parameters.AddWithValue("@Altitude", altitude);
				cmd.Parameters.AddWithValue("@Speed", speed);
				cmd.ExecuteNonQuery();
			}
		}

		/// <summary>
		/// Get markers
		/// </summary>
		/// <param name="gameID"></param>
		/// <returns></returns>
		private static List<Marker> GetMarkerList(int gameID)
		{
			List<Dzzzr.Marker> markers = new List<Marker>();
			using (SqlConnection cnn = Connection)
			{
				SqlCommand cmd = new SqlCommand("GetLastGPSPointByGameID", cnn);
				cmd.CommandType = CommandType.StoredProcedure;
				cmd.Parameters.AddWithValue("@GameID", gameID);
				SqlDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection);
				while (rd.Read())
				{
					Marker marker = new Marker();
					marker.ID = rd.GetInt32(0);
					marker.Name = rd.GetString(1);
					marker.Latitude = rd.GetDouble(2);
					marker.Longitude = rd.GetDouble(3);
					marker.Time = rd.GetDateTime(4);
					marker.Speed = rd.IsDBNull(5) ? new Nullable<double>() : new Nullable<double>(rd.GetDouble(5));
					marker.Altitude = rd.IsDBNull(6) ? new Nullable<double>() : new Nullable<double>(rd.GetDouble(6));
					marker.Delay = rd.IsDBNull(7) ? new Nullable<double>() : new Nullable<double>(rd.GetInt32(7));
					markers.Add(marker);
				}
			}
			return markers;
		}

		/// <summary>
		/// Get markers point
		/// </summary>
		/// <param name="gameID"></param>
		/// <param name="entityID"></param>
		/// <param name="startDate"></param>
		/// <param name="endDate"></param>
		/// <returns></returns>
		private static List<Marker> GetMarkerPointsList(int gameID, int entityID, DateTime startDate, DateTime endDate)
		{
			List<Dzzzr.Marker> markers = new List<Marker>();
			using (SqlConnection cnn = Connection)
			{
				SqlCommand cmd = new SqlCommand("GetGPSPointsByGameIDAndEntityID", cnn);
				cmd.CommandType = CommandType.StoredProcedure;
				cmd.Parameters.AddWithValue("@GameID", gameID);
				cmd.Parameters.AddWithValue("@EntityID", entityID);
				cmd.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime) { Value = startDate });
				cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime) { Value = endDate });
				SqlDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection);
				while (rd.Read())
				{
					Marker marker = new Marker();
					marker.ID = rd.GetInt32(0);
					marker.Name = rd.GetString(1);
					marker.Latitude = rd.GetDouble(2);
					marker.Longitude = rd.GetDouble(3);
					marker.Time = rd.GetDateTime(4);
					marker.Speed = rd.IsDBNull(5) ? new Nullable<double>() : new Nullable<double>(rd.GetDouble(5));
					marker.Altitude = rd.IsDBNull(6) ? new Nullable<double>() : new Nullable<double>(rd.GetDouble(6));
					marker.Delay = rd.IsDBNull(7) ? new Nullable<double>() : new Nullable<double>(rd.GetInt32(7));
					markers.Add(marker);
				}
			}
			return markers;
		}

		/// <summary>
		/// Get count points for marker
		/// </summary>
		/// <param name="gameID"></param>
		/// <param name="markerID"></param>
		/// <param name="count"></param>
		/// <param name="endDate"></param>
		/// <returns></returns>
		public List<Marker> GetMarkerPointsCountList(int gameID, int markerID, int count, DateTime endDate)
		{
			List<Dzzzr.Marker> markers = new List<Marker>();
			using (SqlConnection cnn = Connection)
			{
				SqlCommand cmd = new SqlCommand("GetGPSPointsByGameIDAndEntityIDCount", cnn);
				cmd.CommandType = CommandType.StoredProcedure;
				cmd.Parameters.AddWithValue("@GameID", gameID);
				cmd.Parameters.AddWithValue("@EntityID", markerID);
				cmd.Parameters.AddWithValue("@recordscount", count);
				cmd.Parameters.Add(new SqlParameter("@EndDate", SqlDbType.DateTime) { Value = endDate });
				SqlDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection);
				while (rd.Read())
				{
					Marker marker = new Marker();
					marker.ID = rd.GetInt32(0);
					marker.Name = rd.GetString(1);
					marker.Latitude = rd.GetDouble(2);
					marker.Longitude = rd.GetDouble(3);
					marker.Time = rd.GetDateTime(4);
					marker.Speed = rd.IsDBNull(5) ? new Nullable<double>() : new Nullable<double>(rd.GetDouble(5));
					marker.Altitude = rd.IsDBNull(6) ? new Nullable<double>() : new Nullable<double>(rd.GetDouble(6));
					marker.Delay = rd.IsDBNull(7) ? new Nullable<double>() : new Nullable<double>(rd.GetInt32(7));
					markers.Add(marker);
				}
			}
			return markers;
		}
	}
}